#include "stdafx.h"
#include "Level.h"
#include "Grid.h"
#include "EntityManager.h"
#include "EntityFactory.h"

#include <fstream>

Level::Level(void)
{
}


Level::~Level(void)
{
}

void Level::Init(const String& filename, EntityManager* entity_manager, EntityFactory* entity_factory)
{
	m_entity_types.insert(std::make_pair("tree.obj", EEntityType::Tree));
	m_entity_types.insert(std::make_pair("tower.obj", EEntityType::Basic_Tower));

	LoadLevel(filename, entity_manager, entity_factory);

	// DO STUFF
}

void Level::Shut()
{
	if (m_grid)
	{
		m_grid->Shut();
		delete m_grid;
		m_grid = nullptr;
	}

}

void Level::LoadLevel(const String& filename, EntityManager* entity_manager, EntityFactory* entity_factory)
{
	//****************************
	// Parse level file
	std::ifstream file(filename);

	char input;
	
	file.get(input);

	while (!file.eof())
	{
		switch (input)
		{
		//Comment
		case '#':
			while (input != '\n')
				file.get(input);

			file.get(input);
			break;

		//Gridsize file
		case 'i':
			file >> m_data.grid_size_file;
			file.get(input);
			break;

		//Gridsize
		case 's':
			file >> m_data.square_size_x >> m_data.square_size_z;
			file.get(input);
			break;

		//Object
		case 'o':
			{
			LevelObject obj;
			file >> obj.model_file >> obj.grid_x >> obj.grid_z;
			m_data.objects.push_back(obj);
			}
			file.get(input);
			break;

		default:
			file.get(input);
			break;
		}
	}

	file.close();

	//***************************
	// Create grid from data
	Bitmap bmp;
	bmp.Load(m_data.grid_size_file);

	m_grid = new Grid;
	m_grid->Init(bmp.GetWidth(), bmp.GetHeight(), m_data.square_size_x, m_data.square_size_z);

	// Set black squares to taken spots
	unsigned int bpp = Bitmap::GetFormatSize(bmp.GetFormat());
	unsigned char* data = bmp.GetData();

	m_data.grid_size_x = bmp.GetWidth();
	m_data.grid_size_z = bmp.GetHeight();

	for (unsigned int y = 0; y < m_data.grid_size_z; y++)
	{
		for (unsigned int x = 0; x < m_data.grid_size_x; x++)
		{
			int g = data[((y * 31) + x) * bpp];

			// Count as black pixel
			if (g < 128)
			{
				m_grid->GetSquare(x, y).m_state = Grid::ESquareState::occupied;
			}
			// Count as white pixel
			else
			{
				m_grid->GetSquare(x, y).m_state = Grid::ESquareState::free;
			}
		}
	}


	//***************************
	// Create entities 
	for (unsigned int i = 0; i < m_data.objects.size(); i++)
	{
		LevelObject obj = m_data.objects[i];
		Entity* ent;

		auto it = m_entity_types.find(obj.model_file);

		if (it != m_entity_types.end())
		{
			 ent = entity_factory->Create(it->second, m_grid);
		}
		else
		{
			 ent = entity_factory->Create(EEntityType::N64_Logo, m_grid);
		}
		
		entity_manager->AddEntity(ent);
		ent->SetPosition(m_grid->GetSquare(obj.grid_x, obj.grid_z).m_position);
		m_grid->GetSquare(obj.grid_x, obj.grid_z).m_state = Grid::ESquareState::occupied;
	}
	
}